﻿using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RedisDemo {
    class Program {
        static void Main(string[] args) {

            using (ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("127.0.0.1:6379", a => a.Password = "123456")) {

                IDatabase database = redis.GetDatabase(0);//指定连接的库 0

                database.StringSet("name", "苍");//设置StringSet(key, value)
                string str = database.StringGet("name");//结果：苍
                database.StringSet("name_two", str, TimeSpan.FromSeconds(10));//设置时间，10s后过期。


                //创建对象
                Demo demo = new Demo() {
                    Name = "苍",
                    Age = 18,
                    Height = 1.83
                };

                //String
                string demojson = JsonConvert.SerializeObject(demo);//序列化
                database.StringSet("model", demojson);

                string model = database.StringGet("model");
                demo = JsonConvert.DeserializeObject<Demo>(model);//反序列化


                //增量
                double increment = 0;
                double decrement = 0;
                for (int i = 0; i < 3; i++) {
                    increment = database.StringIncrement("StringIncrement", 2);//增量,每次+2
                }
                for (int i = 0; i < 3; i++) {
                    decrement = database.StringDecrement("StringIncrement");//减量，每次-1
                }

                //List
                for (int i = 0; i < 10; i++) {
                    database.ListRightPush("list", i);//从底部插入数据
                }
                for (int i = 10; i < 20; i++) {
                    database.ListLeftPush("list", i);//从顶部插入数据
                }
                var length = database.ListLength("list");//长度 20

                var rightPop = database.ListRightPop("list");//从底部拿出数据

                var leftpop = database.ListLeftPop("list");//从顶部拿出数据

                var list = database.ListRange("list");


                //Hash
                string json = JsonConvert.SerializeObject(demo);//序列化
                database.HashSet("user", "cang", json);
                database.HashSet("user", "shan", json);
                database.HashSet("user", "yun", json);

                //获取Model
                string hashcang = database.HashGet("user", "cang");
                demo = JsonConvert.DeserializeObject<Demo>(hashcang);//反序列化

                //获取List
                RedisValue[] values = database.HashValues("user");//获取所有value
                IList<Demo> demolist = new List<Demo>();
                foreach (var item in values) {
                    Demo hashmodel = JsonConvert.DeserializeObject<Demo>(item);
                    demolist.Add(hashmodel);
                }


                //发布订阅
                ISubscriber sub = redis.GetSubscriber();

                //订阅 Channel1 频道
                sub.Subscribe("Channel1", new Action<RedisChannel, RedisValue>((channel, message) =>
                {
                    Console.WriteLine("Channel1" + " 订阅收到消息：" + message);
                }));

                for (int i = 0; i < 10; i++) {
                    sub.Publish("Channel1", "msg" + i);//向频道 Channel1 发送信息
                    if (i == 2) {
                        sub.Unsubscribe("Channel1");//取消订阅
                    }
                }

                //事务
                string name = database.StringGet("name");
                string age = database.StringGet("age");
                var tran = database.CreateTransaction();//创建事物
                tran.AddCondition(Condition.StringEqual("name", name));//乐观锁
                tran.StringSetAsync("name", "海");
                tran.StringSetAsync("age", 25);
                database.StringSet("name", "Cang");//此时更改 name 值，提交事物的时候会失败。
                bool committed = tran.Execute();//提交事物，true成功，false回滚。
            }

        }
    }

    class Demo {
        public string Name { get; set; }
        public int Age { get; set; }
        public double Height { get; set; }
    }
}
